﻿using Devil.Persistent;
using GameToolkit.BehaviourTree;
using System.Collections.Generic;
using UnityEngine;

namespace GameToolkit
{
    [System.Serializable]
    [CompositeCategory("")]
    [CompositeTitle("任务子图")]
    public class SubTaskGraphNode : TaskNode, IAliveDescripter
    {
        [SerializeField, AssetPath(typeof(TaskGraphAsset))]
        AssetAddress m_TaskGraphAsset;

        public override TaskEntity Create()
        {
            return new Impl();
        }

        public string GetDescription()
        {
            if (m_TaskGraphAsset.IsNull)
                return "'未指定子图'";
            else
                return m_TaskGraphAsset.ToString();
        }

#if UNITY_EDITOR

        [ContextMenu("Debug Graph", true)]
        bool CanDebug(Impl entity)
        {
            return entity != null && entity.Graph != null;
        }

        [ContextMenu("Debug Graph")]
        void DebugGraph(Impl ent)
        {
            if (ent != null)
                TaskGraphAsset.OpenGraph(ent.Graph);
        }
#endif

        class Impl : TaskEntity, ITick, IReferencedPersistent
        {
            TaskGraph mGraph;
            public TaskGraph Graph => mGraph;

            protected override void OnWarmup(TaskGraph graph)
            {
                mGraph = graph.NewSubGraph(((SubTaskGraphNode)Node).m_TaskGraphAsset);
                //Debug.Log($"Warmup: {((SubTaskGraphNode)Node).m_TaskGraphAsset}");
            }

            protected override void OnRelease(TaskGraph graph)
            {
                if (mGraph != null)
                {
                    //Debug.Log($"Release: {((SubTaskGraphNode)Node).m_TaskGraphAsset}");
                    mGraph.Dispose();
                    mGraph = null;
                }
            }

            protected override void OnEnter(TaskGraph graph)
            {
                mGraph.StartGraph();
                SetState(ETaskState.Processing, 0);
                //Debug.Log($"Enter SubGraph: {((SubTaskGraphNode)Node).m_TaskGraphAsset}");
            }

            protected override void OnExit(TaskGraph graph)
            {
                mGraph.StopGraph();
                SetState(ETaskState.Complete, mGraph.State == ETaskState.Complete ? mGraph.ResultValue : -1);
                //Debug.Log($"Exit SubGraph: {((SubTaskGraphNode)Node).m_TaskGraphAsset}");
            }

            void ITick.OnTick(float deltaTime)
            {
                mGraph.UpdateTaskGraph(deltaTime);
                if (mGraph.State == ETaskState.Complete)
                    SetState(ETaskState.Complete, mGraph.ResultValue);
            }

            void IReferencedPersistent.GetReferencedInstances(ICollection<ISharedInstance> objs)
            {
                if (mGraph != null)
                    objs.Add(mGraph);
            }
        }
    }
}
